{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Say \"Hello World\"  With Qubiter\n",
    "The purpose of this notebook is to illustrate how to use Qubiter to simulate ( i.e., \n",
    "predict the outcome of) a simple quantum circuit with a few basic gates\n",
    "\n",
    "> Below, we won't always give the precise definition of each gate. You can find the\n",
    "precise analytical/numerical definition of all gates implemented by Qubiter in the document entitled `qubiter_rosetta_stone.pdf`  included with the Qubiter distribution."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$\\newcommand{\\bra}[1]{\\left\\langle{#1}\\right|}$\n",
    "$\\newcommand{\\ket}[1]{\\left|{#1}\\right\\rangle}$\n",
    "test: $\\bra{\\psi}M\\ket{\\phi}$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First change your working directory to the Qubiter directory in your computer, and add its path to the path environment variable."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/rrtucci/PycharmProjects/qubiter/qubiter/jupyter_notebooks\n",
      "/home/rrtucci/PycharmProjects/qubiter\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "import sys\n",
    "print(os.getcwd())\n",
    "os.chdir('../../')\n",
    "print(os.getcwd())\n",
    "sys.path.insert(0,os.getcwd())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Suppose you are anywhere in your home ~ directory, and qubiter has been installed somewhere accessible via the path environmental variable. You can find where qubiter is installed like this, in case you want to cd there."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/rrtucci/PycharmProjects/qubiter/qubiter/utilities_gen.py\n"
     ]
    }
   ],
   "source": [
    "from qubiter.utilities_gen import find_path_to_qubiter\n",
    "# this method returns the absolute path to the py file where the method is defined\n",
    "path = find_path_to_qubiter()\n",
    "print(path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loaded OneQubitGate, WITHOUT autograd.numpy\n"
     ]
    }
   ],
   "source": [
    "from qubiter.SEO_writer import *\n",
    "from qubiter.SEO_simulator import *\n",
    "from qubiter.StateVec import *\n",
    "from qubiter.SEO_MatrixProduct import *\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " Sometimes, we use the word \"bit\" to denote both qbits (qubits, quantum bits) or cbits (classical bits).\n",
    " \n",
    " Number of qubits is 4."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "num_qbits = 4"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Use a trivial circuit embedder that embeds 4 qubits into same 4 qubits."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "emb = CktEmbedder(num_qbits, num_qbits)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Open a writer, tell it where to write to.\n",
    "We will use zero bit last (ZL) convention, which is the default for SEO_writer."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "file_prefix = 'hello_world_test'\n",
    "wr = SEO_writer(file_prefix, emb)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Write Pauli matrices $\\sigma_X, \\sigma_Y,\\sigma_Z$ at position 2."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "wr.write_X(2)\n",
    "wr.write_Y(2)\n",
    "wr.write_Z(2)\n",
    "\n",
    "# old way of doing it, still works\n",
    "# wr.write_one_qbit_gate(2, OneQubitGate.sigx)\n",
    "# wr.write_one_qbit_gate(2, OneQubitGate.sigy)\n",
    "# wr.write_one_qbit_gate(2, OneQubitGate.sigz)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Write 1 qubit Hadamard matrix at position 3."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "wr.write_H(3)\n",
    "\n",
    "# old way of doing it, still works\n",
    "# wr.write_one_qbit_gate(3, OneQubitGate.had2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Rotate qubit 2 by $\\pi$ along directions x, y, z successively.\n",
    "\n",
    "> Note: We define $Ra(\\theta) = exp(i\\theta\\sigma_a)$ for $a=X,Y,Z$. Others use \n",
    "$Ra(\\theta) = exp(-i\\frac{\\theta}{2}\\sigma_a)$ instead.\n",
    "\n",
    "> Note: $\\theta$ in $Ra(\\theta)$ is inserted in radians, but shows \n",
    "up in the English File in degrees."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "wr.write_Rx(2, np.pi)\n",
    "wr.write_Ry(2, np.pi)\n",
    "wr.write_Rz(2, np.pi)\n",
    "\n",
    "# old way of doing it, still works dir=1,2,3\n",
    "# wr.write_one_qbit_gate(2, OneQubitGate.rot_ax,[np.pi, dir])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Rotate qubit 1 along a non-axis direction $\\hat{n}$ characterized by a list of 3 angles.\n",
    "$R(\\theta_1, \\theta_2, \\theta_3) = \\exp(i[\\theta_1 \\sigma_X +\\theta_2\\sigma_Y+\\theta_3\\sigma_Z])$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "wr.write_Rn(1, [np.pi, np.pi/2, np.pi/3])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Definitions of S and T\n",
    "\n",
    "$S = diag[1, i] = diag[1, e^{i\\frac{\\pi}{2}}]$\n",
    "\n",
    "$T = \\sqrt{S}= diag[1, e^{i\\frac{\\pi}{4}}]$\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Write  $S, S^\\dagger, T, T^\\dagger$ at position=2.\n",
    "\n",
    "> These operations show up in the English File as `P1PH` and in the \n",
    "Picture File as `@P`. That is because $P_1 = n =\\ket{1}\\bra{1} = diag(0, 1)$ and the operation \n",
    "`P1PH` (i.e. $P_1$ Phase) by a phase angle $\\theta$ equals the diagonal matrix $diag(1, e^{i\\theta})$ "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "wr.write_S(2)\n",
    "wr.write_S(2, herm=True)\n",
    "wr.write_T(2)\n",
    "wr.write_T(2, herm=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Write $CNOT = sigx(target\\_pos)^{n(control\\_pos)}$ with control_pos=3 and target_pos=1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "wr.write_cnot(3, 1)\n",
    "\n",
    "# old way of doing it, still works\n",
    "# control_pos = 3\n",
    "# target_pos = 1\n",
    "# trols = Controls.new_single_trol(num_qbits, control_pos, kind=True)\n",
    "# wr.write_controlled_one_qbit_gate(\n",
    "#     target_pos, trols, OneQubitGate.sigx)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "At any point in the circuit, you can use a PRINT statement. This will print\n",
    "on the console, immediately after you create\n",
    "an object of the class SEO_simulator, a description of the state vector at that point in the circuit.\n",
    "Various styles of description are pre-canned for your convenience, or\n",
    "you can write your own. See use_PRINT() method of SEO_simulator class.\n",
    "Let's use a PRINT statement now in the pre-canned style \"ALL\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "wr.write_PRINT(\"ALL\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Swap qubits 1 and 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "wr.write_qbit_swap(1, 3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " Recall that\n",
    "$P_1 = n = \\ket{1}\\bra{1}=diag(0, 1)$ and a P1 phase (P1PH) by $\\theta$ is $diag(1, e^{i\\theta})$. Write a singly controlled P1PH with control=c=3, target=t=1 and rads = pi/3.\n",
    "This gate equals $e^{i*rads*n(t) n(c)}$. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "wr.write_c_P1PH(3, 1, rads=np.pi/3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If rads=pi, c_P1PH equals  $(-1)^{n(t)n(c)} = \\sigma_Z(t)^{n(c)}$,\n",
    "which is commonly called a controlled Z and denoted by Cz. Write a Cz with c=3 and t=1."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "wr.write_c_P1PH(3, 1)  # rads=np.pi is default"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Write a controlled rotation at qubit 0 in the Y direction, with a True (@) control at qubit 1, and a False (0) control at qubits 2 and 3."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "target_pos = 0\n",
    "rads = 30*np.pi/180\n",
    "ax = 2 # y axis\n",
    "trols = Controls(num_qbits, {1:True, 2:False, 3:False})\n",
    "wr.write_controlled_one_qbit_gate(\n",
    "    target_pos, trols, OneQubitGate.rot_ax, [rads, ax])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Close English and Picture files."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "wr.close_files()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Look in files\n",
    "\n",
    "* <a href=\"../io_folder/hello_world_test_4_eng.txt\">../io_folder/hello_world_test_4_eng.txt</a>\n",
    "* <a href=\"../io_folder/hello_world_test_4_ZLpic.txt\">../io_folder/hello_world_test_4_ZLpic.txt</a>\n",
    "\n",
    "to see the quantum circuit that was generated."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Once the English and Picture files are generated, you can ask the writer object wr to print them for you on screen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table style='font-family:monospace'><tr><td style='border-right:1px solid red;'>1</td><td style='text-align:left;'><pre>SIGX\tAT\t2</pre></td></tr><td style='border-right:1px solid red;'>2</td><td style='text-align:left;'><pre>SIGY\tAT\t2</pre></td></tr><td style='border-right:1px solid red;'>3</td><td style='text-align:left;'><pre>SIGZ\tAT\t2</pre></td></tr><td style='border-right:1px solid red;'>4</td><td style='text-align:left;'><pre>HAD2\tAT\t3</pre></td></tr><td style='border-right:1px solid red;'>5</td><td style='text-align:left;'><pre>ROTX\t180.000000\tAT\t2</pre></td></tr><td style='border-right:1px solid red;'>6</td><td style='text-align:left;'><pre>ROTY\t180.000000\tAT\t2</pre></td></tr><td style='border-right:1px solid red;'>7</td><td style='text-align:left;'><pre>ROTZ\t180.000000\tAT\t2</pre></td></tr><td style='border-right:1px solid red;'>8</td><td style='text-align:left;'><pre>ROTN\t180.000000\t90.000000\t60.000000\tAT\t1</pre></td></tr><td style='border-right:1px solid red;'>9</td><td style='text-align:left;'><pre>P1PH\t90.000000\tAT\t2</pre></td></tr><td style='border-right:1px solid red;'>10</td><td style='text-align:left;'><pre>P1PH\t-90.000000\tAT\t2</pre></td></tr><td style='border-right:1px solid red;'>11</td><td style='text-align:left;'><pre>P1PH\t45.000000\tAT\t2</pre></td></tr><td style='border-right:1px solid red;'>12</td><td style='text-align:left;'><pre>P1PH\t-45.000000\tAT\t2</pre></td></tr><td style='border-right:1px solid red;'>13</td><td style='text-align:left;'><pre>SIGX\tAT\t1\tIF\t3T</pre></td></tr><td style='border-right:1px solid red;'>14</td><td style='text-align:left;'><pre>PRINT\tALL</pre></td></tr><td style='border-right:1px solid red;'>15</td><td style='text-align:left;'><pre>SWAP\t3\t1</pre></td></tr><td style='border-right:1px solid red;'>16</td><td style='text-align:left;'><pre>P1PH\t60.000000\tAT\t1\tIF\t3T</pre></td></tr><td style='border-right:1px solid red;'>17</td><td style='text-align:left;'><pre>P1PH\t180.000000\tAT\t1\tIF\t3T</pre></td></tr><td style='border-right:1px solid red;'>18</td><td style='text-align:left;'><pre>ROTY\t30.000000\tAT\t0\tIF\t3F\t2F\t1T</pre></td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "wr.print_eng_file(jup=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table style='font-family:monospace'><tr><td style='border-right:1px solid red;'>1</td><td style='text-align:left;'><pre>|   X   |   |</pre></td></tr><td style='border-right:1px solid red;'>2</td><td style='text-align:left;'><pre>|   Y   |   |</pre></td></tr><td style='border-right:1px solid red;'>3</td><td style='text-align:left;'><pre>|   Z   |   |</pre></td></tr><td style='border-right:1px solid red;'>4</td><td style='text-align:left;'><pre>H   |   |   |</pre></td></tr><td style='border-right:1px solid red;'>5</td><td style='text-align:left;'><pre>|   Rx  |   |</pre></td></tr><td style='border-right:1px solid red;'>6</td><td style='text-align:left;'><pre>|   Ry  |   |</pre></td></tr><td style='border-right:1px solid red;'>7</td><td style='text-align:left;'><pre>|   Rz  |   |</pre></td></tr><td style='border-right:1px solid red;'>8</td><td style='text-align:left;'><pre>|   |   R   |</pre></td></tr><td style='border-right:1px solid red;'>9</td><td style='text-align:left;'><pre>|   @P  |   |</pre></td></tr><td style='border-right:1px solid red;'>10</td><td style='text-align:left;'><pre>|   @P  |   |</pre></td></tr><td style='border-right:1px solid red;'>11</td><td style='text-align:left;'><pre>|   @P  |   |</pre></td></tr><td style='border-right:1px solid red;'>12</td><td style='text-align:left;'><pre>|   @P  |   |</pre></td></tr><td style='border-right:1px solid red;'>13</td><td style='text-align:left;'><pre>@---+---X   |</pre></td></tr><td style='border-right:1px solid red;'>14</td><td style='text-align:left;'><pre>PRINT\tALL</pre></td></tr><td style='border-right:1px solid red;'>15</td><td style='text-align:left;'><pre><---+--->   |</pre></td></tr><td style='border-right:1px solid red;'>16</td><td style='text-align:left;'><pre>@---+---@P  |</pre></td></tr><td style='border-right:1px solid red;'>17</td><td style='text-align:left;'><pre>@---+---@P  |</pre></td></tr><td style='border-right:1px solid red;'>18</td><td style='text-align:left;'><pre>O---O---@---Ry</pre></td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "wr.print_pic_file(jup=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can ask wr for the path to the English and Picture files"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/rrtucci/PycharmProjects/qubiter/qubiter/io_folder/hello_world_test_4_eng.txt\n"
     ]
    }
   ],
   "source": [
    "print(wr.get_eng_file_path())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/rrtucci/PycharmProjects/qubiter/qubiter/io_folder/hello_world_test_4_ZLpic.txt\n"
     ]
    }
   ],
   "source": [
    "print(wr.get_pic_file_path())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can generate a log file with an inventory of the English file by creating\n",
    "an object of the SEO_reader class with the flag `write_log` set to True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "rdr = SEO_reader(file_prefix, num_qbits, write_log=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The following file was just created\n",
    "\n",
    "* <a href=\"../io_folder/hello_world_test_4_log.txt\">../io_folder/hello_world_test_4_log.txt</a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Once the log file is generated, you can ask the reader object rdr to print it for you on screen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Number of lines in file = 18\n",
      "Number of Elem. Ops = 17\n",
      "Number of CNOTS (SIGX with single control) = 1\n",
      "List of distinct variable numbers encountered (length=0)=\n",
      "[]\n",
      "List of distinct function names encountered (length=0)=\n",
      "[]\n",
      "\n"
     ]
    }
   ],
   "source": [
    "rdr.print_log_file()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can ask rdr for the path to the log file"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/rrtucci/PycharmProjects/qubiter/qubiter/io_folder/hello_world_test_4_log.txt\n"
     ]
    }
   ],
   "source": [
    "print(rdr.get_log_file_path())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Occasionally, especially for debugging purposes, you might want to display the \n",
    "product of a SEO (sequence of elementary operations, sequence of gates) as a 2^num_qbits dimensional\n",
    "unitary matrix. This can be done with the class SEO_MatrixProduct. Simply\n",
    "creating an object of this class multiplies the SEO and stores the result\n",
    "in its attribute `self.prod_arr`. Next we print that array for our example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "product array=\n",
      "[[ 0.1 -0.61j  0.  +0.j    0.3 -0.15j  0.  +0.j   -0.  +0.j    0.  +0.j\n",
      "  -0.  -0.j    0.  +0.j    0.1 -0.61j  0.  +0.j    0.3 -0.15j  0.  +0.j\n",
      "  -0.  +0.j    0.  +0.j   -0.  -0.j    0.  +0.j  ]\n",
      " [ 0.  +0.j    0.1 -0.61j  0.  +0.j    0.3 -0.15j  0.  +0.j   -0.  +0.j\n",
      "   0.  +0.j   -0.  -0.j    0.  +0.j    0.1 -0.61j  0.  +0.j    0.3 -0.15j\n",
      "   0.  +0.j   -0.  +0.j    0.  +0.j   -0.  -0.j  ]\n",
      " [ 0.26+0.13j  0.15+0.08j -0.09-0.53j -0.05-0.31j -0.  -0.j   -0.  -0.j\n",
      "  -0.  +0.j   -0.  +0.j   -0.26-0.13j -0.15-0.08j  0.09+0.53j  0.05+0.31j\n",
      "   0.  +0.j    0.  +0.j    0.  -0.j    0.  -0.j  ]\n",
      " [-0.15-0.08j  0.26+0.13j  0.05+0.31j -0.09-0.53j  0.  +0.j   -0.  -0.j\n",
      "   0.  -0.j   -0.  +0.j    0.15+0.08j -0.26-0.13j -0.05-0.31j  0.09+0.53j\n",
      "  -0.  -0.j    0.  +0.j   -0.  +0.j    0.  -0.j  ]\n",
      " [-0.  -0.j    0.  +0.j    0.  -0.j    0.  +0.j    0.1 -0.61j  0.  +0.j\n",
      "   0.3 -0.15j  0.  +0.j   -0.  -0.j    0.  +0.j    0.  -0.j    0.  +0.j\n",
      "   0.1 -0.61j  0.  +0.j    0.3 -0.15j  0.  +0.j  ]\n",
      " [ 0.  +0.j   -0.  -0.j    0.  +0.j    0.  -0.j    0.  +0.j    0.1 -0.61j\n",
      "   0.  +0.j    0.3 -0.15j  0.  +0.j   -0.  -0.j    0.  +0.j    0.  -0.j\n",
      "   0.  +0.j    0.1 -0.61j  0.  +0.j    0.3 -0.15j]\n",
      " [ 0.  -0.j    0.  +0.j   -0.  -0.j    0.  +0.j    0.3 +0.15j  0.  +0.j\n",
      "  -0.1 -0.61j  0.  +0.j   -0.  +0.j    0.  +0.j    0.  +0.j    0.  +0.j\n",
      "  -0.3 -0.15j  0.  +0.j    0.1 +0.61j  0.  +0.j  ]\n",
      " [ 0.  +0.j    0.  -0.j    0.  +0.j   -0.  -0.j    0.  +0.j    0.3 +0.15j\n",
      "   0.  +0.j   -0.1 -0.61j  0.  +0.j   -0.  +0.j    0.  +0.j    0.  +0.j\n",
      "   0.  +0.j   -0.3 -0.15j  0.  +0.j    0.1 +0.61j]\n",
      " [ 0.3 +0.15j  0.  +0.j   -0.1 -0.61j  0.  +0.j   -0.  -0.j    0.  +0.j\n",
      "  -0.  +0.j    0.  +0.j    0.3 +0.15j  0.  +0.j   -0.1 -0.61j  0.  +0.j\n",
      "  -0.  -0.j    0.  +0.j   -0.  +0.j    0.  +0.j  ]\n",
      " [ 0.  +0.j    0.3 +0.15j  0.  +0.j   -0.1 -0.61j  0.  +0.j   -0.  -0.j\n",
      "   0.  +0.j   -0.  +0.j    0.  +0.j    0.3 +0.15j  0.  +0.j   -0.1 -0.61j\n",
      "   0.  +0.j   -0.  -0.j    0.  +0.j   -0.  +0.j  ]\n",
      " [-0.58+0.22j  0.  +0.j   -0.28-0.19j  0.  +0.j    0.  +0.j    0.  +0.j\n",
      "   0.  +0.j    0.  +0.j    0.58-0.22j  0.  +0.j    0.28+0.19j  0.  +0.j\n",
      "  -0.  -0.j    0.  +0.j   -0.  -0.j    0.  +0.j  ]\n",
      " [ 0.  +0.j   -0.58+0.22j  0.  +0.j   -0.28-0.19j  0.  +0.j    0.  +0.j\n",
      "   0.  +0.j    0.  +0.j    0.  +0.j    0.58-0.22j  0.  +0.j    0.28+0.19j\n",
      "   0.  +0.j   -0.  -0.j    0.  +0.j   -0.  -0.j  ]\n",
      " [ 0.  -0.j    0.  +0.j   -0.  -0.j    0.  +0.j    0.3 +0.15j  0.  +0.j\n",
      "  -0.1 -0.61j  0.  +0.j    0.  -0.j    0.  +0.j   -0.  -0.j    0.  +0.j\n",
      "   0.3 +0.15j  0.  +0.j   -0.1 -0.61j  0.  +0.j  ]\n",
      " [ 0.  +0.j    0.  -0.j    0.  +0.j   -0.  -0.j    0.  +0.j    0.3 +0.15j\n",
      "   0.  +0.j   -0.1 -0.61j  0.  +0.j    0.  -0.j    0.  +0.j   -0.  -0.j\n",
      "   0.  +0.j    0.3 +0.15j  0.  +0.j   -0.1 -0.61j]\n",
      " [-0.  +0.j    0.  +0.j   -0.  +0.j    0.  +0.j   -0.58+0.22j  0.  +0.j\n",
      "  -0.28-0.19j  0.  +0.j    0.  -0.j    0.  +0.j    0.  -0.j    0.  +0.j\n",
      "   0.58-0.22j  0.  +0.j    0.28+0.19j  0.  +0.j  ]\n",
      " [ 0.  +0.j   -0.  +0.j    0.  +0.j   -0.  +0.j    0.  +0.j   -0.58+0.22j\n",
      "   0.  +0.j   -0.28-0.19j  0.  +0.j    0.  -0.j    0.  +0.j    0.  -0.j\n",
      "   0.  +0.j    0.58-0.22j  0.  +0.j    0.28+0.19j]]\n"
     ]
    }
   ],
   "source": [
    "mp = SEO_MatrixProduct(file_prefix, num_qbits)\n",
    "print('product array=')\n",
    "print(np.array_str(mp.prod_arr, \n",
    "                   precision=2, suppress_small=True))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Specify initial state vector for simulation. This example corresponds to $\\ket{0}\\ket{0}\\ket{1}\\ket{1}$. In ZL convention, last ket corresponds to bit 0."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "init_st_vec = StateVec.get_standard_basis_st_vec([0, 0, 1, 1], ZL=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Open a simulator. This automatically\n",
    "calculates the final state vector for the quantum circuit in the English file subject to\n",
    "the initial state vector that you give as input to the SEO_simulator constructor. \n",
    "Note that the PRINT statement that we inserted into the English file, prints, as promised,\n",
    "immediately after creating the SEO_simulator object."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "*************************beginning PRINT output\n",
      "PRINT line number=14\n",
      "*********branch= pure\n",
      "state vector:\n",
      "ZL convention (Zero bit Last in state tuple)\n",
      "(0001)ZL ( 0.303046 - 0.151523j)\t prob=0.114796\n",
      "(1001)ZL (-0.101015 - 0.612372j)\t prob=0.385204\n",
      "(0011)ZL (-0.101015 - 0.612372j)\t prob=0.385204\n",
      "(1011)ZL ( 0.303046 - 0.151523j)\t prob=0.114796\n",
      "total probability of state vector (=one if no measurements)= 1.000000\n",
      "dictionary with key=qubit, value=(Prob(0), Prob(1))\n",
      "{0: (0.0, 1.0), 1: (0.5, 0.5), 2: (1.0, 0.0), 3: (0.5, 0.5)}\n",
      "****************************ending PRINT output\n"
     ]
    }
   ],
   "source": [
    "sim = SEO_simulator(file_prefix, num_qbits, init_st_vec)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ask sim to print a description of final state vector"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "*********branch= pure\n",
      "state vector:\n",
      "ZL convention (Zero bit Last in state tuple)\n",
      "(0010)ZL (-0.050508 - 0.306186j)\t prob=0.096301\n",
      "(0001)ZL ( 0.303046 - 0.151523j)\t prob=0.114796\n",
      "(1001)ZL (-0.101015 - 0.612372j)\t prob=0.385204\n",
      "(0011)ZL (-0.087482 - 0.530330j)\t prob=0.288903\n",
      "(1011)ZL (-0.282746 - 0.186684j)\t prob=0.114796\n",
      "total probability of state vector (=one if no measurements)= 1.000000\n",
      "dictionary with key=qubit, value=(Prob(0), Prob(1))\n",
      "{0: (0.096301, 0.903699), 1: (0.5, 0.5), 2: (1.0, 0.0), 3: (0.5, 0.5)}\n"
     ]
    }
   ],
   "source": [
    "sim.describe_st_vec_dict(print_st_vec=True, do_pp=True,\n",
    "            omit_zero_amps=True, show_pp_probs=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The object sim of SEO_simulator, holds, at this point, the final state vector\n",
    "for the evolution of the circuit subject to the initial state vector chosen. \n",
    "You might want to sample the probability distribution defined\n",
    "by that final state vector, and obtain counts of each observed multi-qubit state\n",
    "for a given number of shots. This is the type\n",
    "of output that a real qc device gives, albeit\n",
    "our counts have no extrinsic noise. One can ask sim to simulate such counts as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "OrderedDict([('0001ZL', 15), ('0010ZL', 11), ('0011ZL', 33), ('1001ZL', 29), ('1011ZL', 12)])\n"
     ]
    }
   ],
   "source": [
    "counts = sim.get_counts(num_shots=100)\n",
    "print(counts)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And you can ask the Plotter class to plot those counts as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "Plotter.plot_counts(counts)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  },
  "toc": {
   "base_numbering": 1,
   "colors": {
    "hover_highlight": "#DAA520",
    "running_highlight": "#FF0000",
    "selected_highlight": "#FFD700"
   },
   "moveMenuLeft": true,
   "nav_menu": {
    "height": "51px",
    "width": "252px"
   },
   "navigate_menu": true,
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "threshold": 4,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": "block",
   "toc_window_display": false,
   "widenNotebook": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
